/**
 * 21point
 *
 * outlook@China software studio
 * Copyright (c) 2008-2010. All Rights Reserved.
 * http://www.outlook.com
 */

package org.outlook.game.arithmetic;

/**
 * function:
 * 
 * @author Watson email: watson.wu@hotmail.com
 * @date 2011
 */
public class NCalculateToM {

	final static double PRECISION = 1E-6;

	private int N = 4;
	private int M = 24;

	private double number[];
	private String[] expression;
	
	public NCalculateToM() {
	}

	public NCalculateToM(int n, int m) {
		N = n;
		M = m;
	}
	
	private void init(int[] numbers) {
		number = new double[N];
		expression = new String[N];
		int i=0;
		for(int num: numbers) {
			number[i] = new Double(num);
			expression[i++] = String.valueOf(num);
		}
	}

	public boolean circule(int[] numbers) {
		init(numbers);
		return circule(N);
	}

	private boolean circule(int n) {
		if (n == 1) {
			if (Math.abs(number[0] - M) < PRECISION) {
				return true;
			} else {
				return false;
			}
		}

		for (int i = 0; i < n; ++i)
			for (int j = i + 1; j < n; ++j) {
				double numi, numj;
				String expi, expj;

				numi = number[i];
				numj = number[j];
				number[j] = number[n - 1];

				expi = expression[i];
				expj = expression[j];
				expression[j] = expression[n - 1];

				// 加的处理
				if (n > 2)
					expression[i] = "(" + expi + "+" + expj + ")";
				else
					expression[i] = expi + "+" + expj;
				number[i] = numi + numj;
				if (circule(n - 1))
					return true;

				// 减的处理，有两种情况expi-expj,expj-expi
				if (n > 2)
					expression[i] = '(' + expi + '-' + expj + ')';
				else
					expression[i] = expi + '-' + expj;
				number[i] = numi - numj;
				if (circule(n - 1))
					return true;

				if (n > 2)
					expression[i] = '(' + expj + '-' + expi + ')';
				else
					expression[i] = expj + '-' + expi;
				number[i] = numj - numi;
				if (circule(n - 1))
					return true;

				// 乘的处理
				expression[i] = expi + "*" + expj;
				number[i] = numi * numj;
				if (circule(n - 1))
					return true;

				// 除的处理，有两种情况expi/expj,expj/expi
				if (numj > PRECISION) {
					expression[i] = expi + '/' + expj;
					number[i] = numi / numj;
					if (circule(n - 1))
						return true;
				}

				if (numi > PRECISION) {
					expression[i] = expj + '/' + expi;
					number[i] = numj / numi;
					if (circule(n - 1))
						return true;
				}

				// 恢复数组
				number[i] = numi;
				number[j] = numj;
				expression[i] = expi;
				expression[j] = expj;

			}

		return false;
	}

	public String[] getExpression() {
		return expression;
	}

	public void setExpression(String[] expression) {
		this.expression = expression;
	}

	public int getN() {
		return N;
	}

	public void setN(int n) {
		N = n;
	}

	public int getM() {
		return M;
	}

	public void setM(int m) {
		M = m;
	}

}
